#pragma once

#include "Defines.h"

#pragma pack(1) 

// Ethernet Header
struct EthernetHeader 
{
	unsigned char	DestinationAddress[ETH_ALEN];	/* destination eth addr	*/
	unsigned char	SourceAddress[ETH_ALEN];		/* source ether addr	*/
	unsigned short	Protocol;						/* packet type ID field	*/
};

struct ArpHeader
{
	unsigned short	HardwareFormat;			/* format of hardware address	*/
	unsigned short	ProtocolFormat;			/* format of protocol address	*/
	unsigned char	HardwareAddrLength;		/* length of hardware address	*/
	unsigned char	ProtocolAddrLength;		/* length of protocol address	*/
	unsigned short	OpCode;					/* ARP opcode (command)		*/
};

struct EthernetArp 
{
	struct			ArpHeader ArpHeader;				/* fixed-size header */
	unsigned char	SenderAddress[ETH_ALEN];			/* sender hardware address */
	unsigned char	SenderProtocolAddress[4];			/* sender protocol address */
	unsigned char	TargetHardwareAddress[ETH_ALEN];	/* target hardware address */
	unsigned char	TargetProtocolAddress[4];			/* target protocol address */
};

#define	arp_hrd	ea_hdr.ar_hrd
#define	arp_pro	ea_hdr.ar_pro
#define	arp_hln	ea_hdr.ar_hln
#define	arp_pln	ea_hdr.ar_pln
#define	arp_op	ea_hdr.ar_op

/* IP Header in Little Endian */
struct IpHeader 
{
	unsigned char	HeaderLength:4,			/* header length */
					IpVersion:4;			/* version */
	unsigned char	TypeOfService;			/* type of service */
	short			TotalLength;			/* total length */
	unsigned short	ID;						/* identification */
	short			FragmentOffset;			/* fragment offset field */
	unsigned char	TimeToLive;				/* time to live */
	unsigned char	Protocol;				/* protocol */
	unsigned short	Checksum;				/* checksum */
	struct	in_addr SourceAddress;			/* source IP address */
	struct	in_addr DestinationAddress;		/* destination IP address */
};

struct UdpHeader
{
	unsigned short	SourcePort;		/* source port */
	unsigned short	DestPort;		/* destination port */
	unsigned short	Length;			/* data length */
	unsigned short	Checksum;			/* checksum */
};

struct TcpHeader
{
	unsigned short	SourcePort;		/* source port */
	unsigned short	DestPort;		/* destination port */
	unsigned long	SequenceNo;		/* sequence number */
	unsigned long	AckNo;			/* acknowledgement number */
	unsigned char	X2:4,			/* (unused) */
					DataOffset:4;	/* data offset */
	unsigned char	TcpFlags;
	unsigned short	WindowSize;		/* window */
	unsigned short	CheckSum;		/* checksum */
	unsigned short	UrgentPointer;	/* urgent pointer */
};

struct PseudoHeader
{
  struct in_addr	SourceAddress;
  struct in_addr	DestAddress;
  unsigned char		Placeholder;
  unsigned char		Protocol;
  unsigned short	TcpLength;
};

struct TcpPacketContent
{
	EthernetHeader	EtherHeader;
	IpHeader		IPHeader;
	TcpHeader		TCPHeader;
};

struct UdpPacketContent
{
	EthernetHeader	EtherHeader;
	IpHeader		IPHeader;
	UdpHeader		UDPHeader;
};

#pragma pack()
